<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FMCW雷达波形参数计算器</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <!-- 引入KaTeX用于LaTeX公式渲染 -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.css">
    <script src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/katex.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/katex@0.16.8/dist/contrib/auto-render.min.js"></script>
    
    <!-- Tailwind配置 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#165DFF',
                        secondary: '#36CFC9',
                        neutral: '#F5F7FA',
                        dark: '#1D2129',
                        light: '#FFFFFF',
                        success: '#22C55E', // 醒目绿色
                        warning: '#FAAD14',
                        danger: '#EF4444',  // 醒目红色
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .card-shadow {
                box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            }
            .input-focus {
                @apply focus:border-primary focus:ring-2 focus:ring-primary/20 focus:outline-none;
            }
            .transition-all-300 {
                transition: all 0.3s ease;
            }
            .btn-primary {
                @apply bg-primary text-white px-4 py-2 rounded-lg hover:bg-primary/90 transition-all-300 
                       flex items-center justify-center gap-2 font-medium;
            }
            .btn-outline {
                @apply border border-primary text-primary px-4 py-2 rounded-lg hover:bg-primary/10 
                       transition-all-300 flex items-center justify-center gap-2 font-medium;
            }
            .toast {
                @apply fixed bottom-6 right-6 bg-dark text-white px-6 py-3 rounded-lg shadow-lg 
                       transform translate-y-20 opacity-0 transition-all duration-300 z-50;
            }
            .toast.show {
                @apply translate-y-0 opacity-100;
            }
            /* 结果网格布局 - 严格两行两列 */
            .results-container-wrapper {
                display: grid;
                grid-template-columns: 1fr 1fr;
                grid-template-rows: 1fr 1fr;
                gap: 1rem;
                height: calc(100% - 2rem);
            }
            /* 确保每个网格项高度一致 */
            .results-container-wrapper > div {
                display: flex;
                flex-direction: column;
            }
            /* 参数组容器 */
            .param-group {
                display: flex;
                flex-direction: column;
                gap: 0.5rem;
                padding: 0.75rem;
                border-radius: 8px;
                background-color: #f9fafb;
                flex: 1;
            }
            /* 参数组标题 */
            .group-title {
                font-size: 0.9rem;
                font-weight: 600;
                color: #1D2129;
                padding-bottom: 0.35rem;
                border-bottom: 1px solid #E5E6EB;
                display: flex;
                align-items: center;
            }
            .group-title i {
                color: #165DFF;
                margin-right: 0.5rem;
                font-size: 0.85rem;
            }
            /* 参数项网格 - 两列布局 */
            .param-items {
                display: grid;
                grid-template-columns: 1fr 1fr;
                gap: 0.75rem;
                margin-top: 0.25rem;
                flex: 1;
                align-content: start;
            }
            /* 结果卡片样式 */
            .result-card {
                min-width: 0;
                padding: 0.75rem;
                border-radius: 6px;
                border: 1px solid #E5E6EB;
                display: flex;
                flex-direction: column;
                gap: 0.25rem;
                font-size: 0.85rem;
                background-color: white;
                transition: all 0.2s ease;
            }
            .result-card:hover {
                border-color: #165DFF33;
                background-color: #f0f7ff;
                transform: translateY(-2px);
                box-shadow: 0 2px 8px rgba(22, 93, 255, 0.1);
            }
            /* 重要参数高亮 */
            .result-card.important {
                border-color: #165DFF33;
                background-color: #f0f7ff;
            }
            /* 公式样式 */
            .param-formula {
                line-height: 1.4;
                color: #1D2129;
                padding-bottom: 0.15rem;
            }
            /* 参数名称 */
            .param-name {
                font-size: 0.75rem;
                color: #6B7785;
                line-height: 1.2;
            }
            /* 参数值 */
            .param-value {
                font-weight: 600;
                color: #165DFF;
                line-height: 1.3;
            }
            /* 最终结果样式 */
            .final-result {
                grid-column: 1 / -1;
                border: 2px solid #FF4D4F !important;
                background-color: rgba(255, 77, 79, 0.05) !important;
                padding: 0.85rem;
                margin-top: 0.5rem;
            }
            /* 公式字体大小调整 */
            .katex {
                font-size: 1.1em !important;
            }
            /* 状态颜色增强 */
            .status-success {
                color: #22C55E !important;
                font-weight: 700;
            }
            .status-danger {
                color: #EF4444 !important;
                font-weight: 700;
            }
            /* 响应式调整 */
            @media (max-width: 1024px) {
                .results-container-wrapper {
                    grid-template-columns: 1fr;
                    grid-template-rows: auto;
                }
            }
            @media (max-width: 640px) {
                .param-items {
                    grid-template-columns: 1fr;
                }
                .katex {
                    font-size: 1.0em !important;
                }
            }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans text-dark">
    <div class="container mx-auto px-3 py-5 max-w-7xl">
        <!-- 标题区域 -->
        <header class="text-center mb-6">
            <h1 class="text-[clamp(1.4rem,3vw,2rem)] font-bold text-primary mb-2">FMCW雷达波形参数计算器</h1>
            <p class="text-gray-600 max-w-3xl mx-auto text-sm">实时计算调频连续波(FMCW)雷达的关键参数，支持自定义输入与动态结果更新</p>
        </header>
        
        <!-- 主要内容区域 -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
            <!-- 左侧区域：上方是示意图，下方是输入参数 -->
            <div class="flex flex-col gap-6">
                <!-- 单脉冲参数配图 -->
                <div class="bg-white rounded-xl p-4 card-shadow">
                    <h2 class="text-base font-semibold mb-3 flex items-center">
                        <i class="fa fa-line-chart text-primary mr-2"></i>单脉冲（Chirp）参数示意图
                    </h2>
                    <div class="overflow-hidden rounded-lg">
                        <img src="https://dev.ti.com/gallery/view/mmwave/mmWaveSensingEstimator/ver/2.5.1/app/chirp_diagram.png" 
                             alt="FMCW单脉冲参数示意图" 
                             title="FMCW Chirp波形参数"
                             class="w-full h-auto hover:scale-105 transition-all duration-500">
                    </div>
                </div>
                
                <!-- 输入参数区域 -->
                <div class="bg-white rounded-xl p-5 card-shadow flex-grow">
                    <h2 class="text-base font-semibold mb-4 flex items-center">
                        <i class="fa fa-sliders text-primary mr-2"></i>输入参数配置
                    </h2>
                    
                    <div class="space-y-4">
                        <!-- 基本参数组 -->
                        <div class="border-b border-gray-100 pb-4">
                            <h3 class="text-xs font-medium text-gray-700 mb-3">基本参数</h3>
                            
                            <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <div class="space-y-1">
                                    <label for="fc" class="block text-xs font-medium text-gray-700">中心频率 (fc, GHz)</label>
                                    <input type="number" id="fc" value="77" min="1" step="0.1" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">典型值：77-81 GHz</p>
                                </div>
                                
                                <div class="space-y-1">
                                    <label for="bandwidth" class="block text-xs font-medium text-gray-700">扫频带宽 (MHz)</label>
                                    <input type="number" id="bandwidth" value="4000" min="100" step="100" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">带宽越大，距离分辨率越高</p>
                                </div>
                            </div>
                        </div>
                        
                        <!-- 天线参数组 -->
                        <div class="border-b border-gray-100 pb-4">
                            <h3 class="text-xs font-medium text-gray-700 mb-3">天线参数</h3>
                            
                            <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <div class="space-y-1">
                                    <label for="k" class="block text-xs font-medium text-gray-700">天线间距倍数 (k, 倍波长)</label>
                                    <input type="number" id="k" value="0.5" min="0.1" step="0.1" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">推荐0.5（λ/2）</p>
                                </div>
                                
                                <div class="grid grid-cols-1 gap-3">
                                    <div class="space-y-1">
                                        <label for="ntx" class="block text-xs font-medium text-gray-700">Tx发射通道数量 (Nₜₓ)</label>
                                        <input type="number" id="ntx" value="1" min="1" max="16" step="1" 
                                            class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                        <p class="text-xs text-gray-500">常见1-16通道</p>
                                    </div>
                                    
                                    <div class="space-y-1">
                                        <label for="nrx" class="block text-xs font-medium text-gray-700">Rx接收通道数量 (Nᵣₓ)</label>
                                        <input type="number" id="nrx" value="4" min="1" max="16" step="1" 
                                            class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                        <p class="text-xs text-gray-500">影响角度分辨率</p>
                                    </div>
                                </div>
                            </div>
                        </div>
                        
                        <!-- FFT参数组 -->
                        <div class="border-b border-gray-100 pb-4">
                            <h3 class="text-xs font-medium text-gray-700 mb-3">FFT参数</h3>
                            
                            <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <div class="space-y-1">
                                    <label for="nr" class="block text-xs font-medium text-gray-700">距离FFT点数 (Nᵣ)</label>
                                    <input type="number" id="nr" value="256" min="16" step="16" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">2的幂次最佳</p>
                                </div>
                                
                                <div class="space-y-1">
                                    <label for="nv" class="block text-xs font-medium text-gray-700">速度FFT点数 (Nᵥ)</label>
                                    <input type="number" id="nv" value="64" min="8" step="8" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">决定速度分辨率</p>
                                </div>
                            </div>
                        </div>
                        
                        <!-- 时间参数组 -->
                        <div class="border-b border-gray-100 pb-4">
                            <h3 class="text-xs font-medium text-gray-700 mb-3">时间参数</h3>
                            
                            <div class="grid grid-cols-1 md:grid-cols-2 gap-3">
                                <div class="space-y-1">
                                    <label for="rampEndTime" class="block text-xs font-medium text-gray-700">Ramp结束时间 (μs)</label>
                                    <input type="number" id="rampEndTime" value="40" min="1" step="1" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">Chirp持续时间</p>
                                </div>
                                
                                <div class="space-y-1">
                                    <label for="idleTime" class="block text-xs font-medium text-gray-700">空闲时间 (μs)</label>
                                    <input type="number" id="idleTime" value="10" min="0" step="1" 
                                        class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                    <p class="text-xs text-gray-500">Chirp之间的空闲时间</p>
                                </div>
                            </div>
                        </div>
                        
                        <!-- 角度分辨率要求 -->
                        <div>
                            <h3 class="text-xs font-medium text-gray-700 mb-3">角度分辨率要求</h3>
                            
                            <div class="space-y-1">
                                <label for="requiredAngleRes" class="block text-xs font-medium text-gray-700">所需角度分辨率 (°)</label>
                                <input type="number" id="requiredAngleRes" value="3.0" min="0.1" step="0.1" 
                                    class="w-full px-3 py-2 border border-gray-300 rounded-lg input-focus transition-all-300 text-sm">
                                <p class="text-xs text-gray-500">根据应用场景需求设定</p>
                            </div>
                        </div>
                    </div>
                    
                    <div class="mt-4 text-center">
                        <p id="error" class="text-danger font-medium text-sm hidden"></p>
                    </div>
                </div>
            </div>
            
            <!-- 右侧：波形参数计算结果 - 严格两行两列布局 -->
            <div class="bg-white rounded-xl p-5 card-shadow h-full" style="width: 770px;">
                <div class="flex justify-between items-center mb-5">
                    <h2 class="text-base font-semibold flex items-center">
                        <i class="fa fa-calculator text-primary mr-2"></i>波形参数计算结果
                    </h2>
                    <div class="flex gap-2">
                        <button id="exportCsvBtn" class="btn-primary text-xs py-1">
                            <i class="fa fa-download"></i> 导出CSV
                        </button>
                        <button id="exportTxtBtn" class="btn-outline text-xs py-1">
                            <i class="fa fa-file-text-o"></i> 导出文本
                        </button>
                    </div>
                </div>
                
                <div class="results-container-wrapper" id="results-container">
                    <!-- 计算结果将通过JS动态插入 -->
                </div>
            </div>
        </div>
        
        <!-- 页脚 -->
        <footer class="mt-8 text-center text-gray-500 text-xs">
            <p>© 2025 FMCW雷达波形参数计算器 | 基于雷达系统设计原理</p>
        </footer>
    </div>

    <!-- 提示框 -->
    <div id="toast" class="toast">
        <span id="toastMessage"></span>
    </div>

    <script>
        // 物理常数
        const c = 3e8;          // 光速 (m/s)
        let currentResults = []; // 存储当前计算结果，用于导出

        // 获取DOM元素
        const fcInput = document.getElementById('fc');
        const bandwidthInput = document.getElementById('bandwidth');
        const kInput = document.getElementById('k');
        const nrInput = document.getElementById('nr');
        const nvInput = document.getElementById('nv');
        const ntxInput = document.getElementById('ntx');
        const nrxInput = document.getElementById('nrx');
        const rampEndTimeInput = document.getElementById('rampEndTime');
        const idleTimeInput = document.getElementById('idleTime');
        const requiredAngleResInput = document.getElementById('requiredAngleRes');
        const errorElem = document.getElementById('error');
        const resultsContainer = document.getElementById('results-container');
        const exportCsvBtn = document.getElementById('exportCsvBtn');
        const exportTxtBtn = document.getElementById('exportTxtBtn');
        const toast = document.getElementById('toast');
        const toastMessage = document.getElementById('toastMessage');

        // 输入参数数组（用于批量监听事件）
        const inputs = [
            fcInput, bandwidthInput, kInput, nrInput, nvInput, 
            ntxInput, nrxInput, rampEndTimeInput, idleTimeInput, requiredAngleResInput
        ];

        // 页面加载完成后初始化计算
        document.addEventListener('DOMContentLoaded', function() {
            calculateParams();
        });

        // 监听所有输入框变化，实时更新计算结果
        inputs.forEach(input => {
            input.addEventListener('input', calculateParams);
            input.addEventListener('change', calculateParams);
        });

        // 绑定导出按钮事件
        exportCsvBtn.addEventListener('click', () => exportResults('csv'));
        exportTxtBtn.addEventListener('click', () => exportResults('txt'));

        // 核心计算函数
        function calculateParams() {
            // 1. 获取输入值并验证
            const fc = parseFloat(fcInput.value);            // 中心频率 (GHz)
            const bandwidth = parseFloat(bandwidthInput.value);  // 扫频带宽 (MHz)
            const k = parseFloat(kInput.value);              // 天线间距倍数
            const nr = parseInt(nrInput.value);              // 距离FFT点数
            const nv = parseInt(nvInput.value);              // 速度FFT点数
            const ntx = parseInt(ntxInput.value);            // Tx数量
            const nrx = parseInt(nrxInput.value);            // Rx数量
            const rampEndTime = parseFloat(rampEndTimeInput.value);  // Ramp结束时间 (μs)
            const idleTime = parseFloat(idleTimeInput.value);      // 空闲时间 (μs)
            const requiredAngleRes = parseFloat(requiredAngleResInput.value);  // 所需角度分辨率 (°)

            // 验证输入合法性
            errorElem.classList.add('hidden');
            let errorMessage = '';
            
            if (isNaN(fc) || fc <= 0) errorMessage = '中心频率必须为正数';
            else if (isNaN(bandwidth) || bandwidth <= 0) errorMessage = '扫频带宽必须为正数';
            else if (isNaN(k) || k <= 0) errorMessage = '天线间距倍数必须为正数';
            else if (isNaN(nr) || nr < 16) errorMessage = '距离FFT点数至少为16';
            else if (isNaN(nv) || nv < 8) errorMessage = '速度FFT点数至少为8';
            else if (isNaN(rampEndTime) || rampEndTime <= 0) errorMessage = 'Ramp结束时间必须为正数';
            else if (isNaN(idleTime) || idleTime < 0) errorMessage = '空闲时间不能为负数';
            else if (isNaN(requiredAngleRes) || requiredAngleRes <= 0) errorMessage = '所需角度分辨率必须为正数';
            
            if (errorMessage) {
                errorElem.textContent = `错误：${errorMessage}`;
                errorElem.classList.remove('hidden');
                return;
            }

            // 2. 转换单位
            const fcHz = fc * 1e9;          // 中心频率转Hz
            const B = bandwidth * 1e6;      // 带宽转Hz
            const Tc = rampEndTime * 1e-6;  // Ramp结束时间转秒
            const idleTimeSec = idleTime * 1e-6;  // 空闲时间转秒
            const requiredAngleResRad = requiredAngleRes * (Math.PI / 180);  // 所需角度分辨率转弧度

            // 3. 计算核心参数
            const lambda = c / fcHz;                 // 波长
            const dAnt = k * lambda;                 // 实际天线间距
            
            // MIMO体制下的通道总数计算：Tx × Rx
            const mimoChannels = ntx * nrx;
            
            // 计算满足角度分辨率要求所需的总通道数
            const requiredTotalChannels = Math.ceil(1 / (k * requiredAngleResRad));
            const channelSufficiency = requiredTotalChannels <= mimoChannels ? "满足要求" : "不满足要求";
            
            const dRes = c / (2 * B);                // 距离分辨率
            const dMax = nr * dRes;                  // 最大距离
            const slope = B / Tc;                    // 调频斜率
            const chirpRepTime = Tc + idleTimeSec;   // Chirp重复时间
            const frameTime = nv * chirpRepTime;     // 帧时间
            const maxUnambiguousVelocity = lambda / (4 * chirpRepTime);  // 最大无模糊速度
            const velocityResolution = lambda / (2 * frameTime);          // 速度分辨率
            const maxUnambiguousRange = (c * chirpRepTime) / 2;           // 最大无模糊距离
            const thetaMax = Math.asin(1/(2*k)) * (180/Math.PI);          // 最大角度
            const thetaRes = (1/(mimoChannels * k)) * (180/Math.PI);      // 角度分辨率

            // 4. 格式化计算结果 - 按四组参数组织，严格适应两行两列布局
            const tempResults = [
                // 第一组：基本与MIMO参数（左上角）
                {
                    group: "基本与MIMO参数",
                    icon: "fa-cogs",
                    name: '波长 (λ)',
                    value: lambda.toFixed(6),
                    unit: 'm',
                    basis: '\\lambda = \\frac{c}{f_c}'
                },
                {
                    group: "基本与MIMO参数",
                    icon: "fa-cogs",
                    name: '实际天线间距',
                    value: dAnt.toFixed(6),
                    unit: 'm',
                    basis: 'd_{ant} = k \\times \\lambda'
                },
                {
                    group: "基本与MIMO参数",
                    icon: "fa-cogs",
                    name: '发射通道数 (Tx)',
                    value: ntx,
                    unit: '个',
                    basis: 'N_{tx}'
                },
                {
                    group: "基本与MIMO参数",
                    icon: "fa-cogs",
                    name: '接收通道数 (Rx)',
                    value: nrx,
                    unit: '个',
                    basis: 'N_{rx}'
                },
                {
                    group: "基本与MIMO参数",
                    icon: "fa-cogs",
                    name: 'MIMO总通道数',
                    value: mimoChannels,
                    unit: '个',
                    basis: 'N_{total} = N_{tx} \\times N_{rx}',
                    important: true
                },
                
                // 第二组：距离参数（右上角）
                {
                    group: "距离参数",
                    icon: "fa-arrows-h",
                    name: '距离分辨率 (d_res)',
                    value: (dRes * 100).toFixed(2),
                    unit: 'cm',
                    basis: 'd_{res} = \\frac{c}{2B}',
                    important: true
                },
                {
                    group: "距离参数",
                    icon: "fa-arrows-h",
                    name: '最大探测距离',
                    value: dMax.toFixed(2),
                    unit: 'm',
                    basis: 'd_{max} = N_r \\times d_{res}'
                },
                {
                    group: "距离参数",
                    icon: "fa-arrows-h",
                    name: '最大无模糊距离',
                    value: maxUnambiguousRange.toFixed(2),
                    unit: 'm',
                    basis: 'R_{max} = \\frac{c \\times T_{ramp}}{2}'
                },
                {
                    group: "距离参数",
                    icon: "fa-wave-square",
                    name: '调频斜率',
                    value: (slope * 1e-15).toFixed(2),
                    unit: 'GHz/μs',
                    basis: 'S = \\frac{B}{T_c}'
                },
                
                // 第三组：时间与速度参数（左下角）
                {
                    group: "时间与速度参数",
                    icon: "fa-clock-o",
                    name: 'Chirp重复时间',
                    value: (chirpRepTime * 1e6).toFixed(2),
                    unit: 'μs',
                    basis: 'T_{ramp} = T_c + T_{idle}'
                },
                {
                    group: "时间与速度参数",
                    icon: "fa-clock-o",
                    name: '脉冲重复频率 (PRF)',
                    value: (1 / chirpRepTime).toFixed(0),
                    unit: 'Hz',
                    basis: 'PRF = \\frac{1}{T_{ramp}}'
                },
                {
                    group: "时间与速度参数",
                    icon: "fa-clock-o",
                    name: '帧时间',
                    value: (frameTime * 1000).toFixed(3),
                    unit: 'ms',
                    basis: 'T_{frame} = N_v \\times T_{ramp}'
                },
                {
                    group: "时间与速度参数",
                    icon: "fa-tachometer",
                    name: '最大无模糊速度',
                    value: maxUnambiguousVelocity.toFixed(2),
                    unit: 'm/s',
                    basis: 'v_{max} = \\frac{\\lambda}{4 \\times T_{ramp}}'
                },
                {
                    group: "时间与速度参数",
                    icon: "fa-tachometer",
                    name: '速度分辨率',
                    value: velocityResolution.toFixed(3),
                    unit: 'm/s',
                    basis: 'v_{res} = \\frac{\\lambda}{2 \\times T_{frame}}',
                    important: true
                },
                
                // 第四组：角度参数（右下角）
                {
                    group: "角度参数",
                    icon: "fa-compass",
                    name: '满足角度分辨率所需总通道数',
                    value: requiredTotalChannels,
                    unit: '个',
                    basis: 'N_{total} \\geq \\frac{1}{k \\times \\theta_{res}}',
                    important: true
                },
                {
                    group: "角度参数",
                    icon: "fa-compass",
                    name: '最大探测角度 (θ_max)',
                    value: thetaMax.toFixed(1),
                    unit: '°',
                    basis: '\\theta_{max} = \\arcsin\\left(\\frac{\\lambda}{2d_{ant}}\\right)'
                },
                {
                    group: "角度参数",
                    icon: "fa-compass",
                    name: '角度分辨率 (θ_res)',
                    value: thetaRes.toFixed(2),
                    unit: '°',
                    basis: '\\theta_{res} = \\frac{\\lambda}{N_{total} \\times d_{ant}}',
                    important: true
                },
                {
                    group: "角度参数",
                    icon: "fa-check-circle",
                    name: '总通道数是否满足要求',
                    value: channelSufficiency,
                    unit: '',
                    basis: '所需总通道数',
                    important: true,
                    isFinal: true
                }
            ];

            currentResults = tempResults;
            updateResultsDisplay();
        }

        // 更新结果显示并渲染LaTeX公式
        function updateResultsDisplay() {
            resultsContainer.innerHTML = '';
            
            // 按参数组组织结果 - 确保正好四组参数，对应两行两列
            const groups = {};
            currentResults.forEach(param => {
                if (!groups[param.group]) {
                    groups[param.group] = [];
                }
                groups[param.group].push(param);
            });
            
            // 处理每个参数组，严格形成两行两列布局
            Object.entries(groups).forEach(([groupName, params]) => {
                // 创建参数组容器
                const groupContainer = document.createElement('div');
                groupContainer.className = 'param-group';
                groupContainer.style.height = '400px';

                
                // 创建组标题，添加图标
                const groupHeader = document.createElement('div');
                groupHeader.className = 'group-title';
                groupHeader.innerHTML = `<i class="fa ${params[0].icon}"></i>${groupName}`;
                groupContainer.appendChild(groupHeader);
                
                // 创建参数项网格（两列布局）
                const paramItemsContainer = document.createElement('div');
                paramItemsContainer.className = 'param-items';
                
                // 添加组内所有参数
                params.forEach(param => {                    
                    const resultCard = document.createElement('div');
                    // 保持最终结果的样式突出显示
                    const cardClass = param.isFinal ? 'result-card final-result' : `result-card ${param.important ? 'important' : ''}`;
                    resultCard.className = cardClass;
                    resultCard.style.width = '160px';
                    
                    // 创建公式容器
                    const basisContainer = document.createElement('div');
                    basisContainer.className = 'param-formula';
                    basisContainer.setAttribute('data-latex', param.basis);
                    
                    // 创建参数名称和值容器
                    const nameContainer = document.createElement('div');
                    nameContainer.className = 'param-name';
                    nameContainer.textContent = param.name;
                    
                    const valueContainer = document.createElement('div');
                    // 应用状态颜色
                    if (param.isFinal) {
                        const valueClass = param.value === "满足要求" ? "status-success" : "status-danger";
                        valueContainer.className = `param-value ${valueClass}`;
                    } else {
                        valueContainer.className = 'param-value';
                    }
                    valueContainer.textContent = `${param.value} ${param.unit}`;
                    
                    // 按公式 → 中文名称 → 结果的顺序组织
                    resultCard.appendChild(basisContainer);
                    resultCard.appendChild(nameContainer);
                    resultCard.appendChild(valueContainer);
                    
                    paramItemsContainer.appendChild(resultCard);
                });
                
                groupContainer.appendChild(paramItemsContainer);
                resultsContainer.appendChild(groupContainer);
            });
            
            // 确保DOM更新完成后再渲染公式
            setTimeout(() => {
                // 对每个公式容器单独渲染
                document.querySelectorAll('[data-latex]').forEach(el => {
                    const latex = el.getAttribute('data-latex');
                    el.textContent = ''; // 清空容器
                    katex.render(latex, el, {
                        throwOnError: false,
                        displayMode: false
                    });
                });
            }, 0);
        }

        // 导出结果
        function exportResults(format) {
            if (currentResults.length === 0) {
                showToast('没有可导出的计算结果');
                return;
            }

            // 获取当前输入参数，用于导出文件头
            const inputParams = {
                '中心频率 (GHz)': fcInput.value,
                '扫频带宽 (MHz)': bandwidthInput.value,
                '天线间距倍数': kInput.value,
                '距离FFT点数': nrInput.value,
                '速度FFT点数': nvInput.value,
                'Tx发射通道数量': ntxInput.value,
                'Rx接收通道数量': nrxInput.value,
                'Ramp结束时间 (μs)': rampEndTimeInput.value,
                '空闲时间 (μs)': idleTimeInput.value,
                '所需角度分辨率 (°)': requiredAngleResInput.value
            };

            let content = '';
            let fileName = `fmcw_radar_parameters_${getCurrentDateTime()}`;

            if (format === 'csv') {
                fileName += '.csv';
                content += '输入参数,值\n';
                Object.entries(inputParams).forEach(([name, value]) => {
                    content += `${escapeCsv(name)},${escapeCsv(value)}\n`;
                });
                
                content += '\n';
                content += '参数组,参数名称,值,单位,计算依据\n';
                currentResults.forEach(param => {
                    const plainBasis = param.basis.replace(/\\/g, '').replace(/\{|\}|\(|\)|\[|\]|\/|_|\^|~/g, '');
                    content += `${escapeCsv(param.group)},${escapeCsv(param.name)},${escapeCsv(param.value)},${escapeCsv(param.unit)},${escapeCsv(plainBasis)}\n`;
                });
            } else {
                fileName += '.txt';
                content += 'FMCW雷达波形参数计算结果\n';
                content += `导出时间: ${new Date().toLocaleString()}\n\n`;
                
                content += '=== 输入参数 ===\n';
                Object.entries(inputParams).forEach(([name, value]) => {
                    content += `${name}: ${value}\n`;
                });
                
                const groups = {};
                currentResults.forEach(param => {
                    if (!groups[param.group]) {
                        groups[param.group] = [];
                    }
                    groups[param.group].push(param);
                });
                
                Object.entries(groups).forEach(([groupName, params]) => {
                    content += `\n=== ${groupName} ===\n`;
                    params.forEach(param => {
                        const plainBasis = param.basis.replace(/\\/g, '').replace(/\{|\}|\(|\)|\[|\]|\/|_|\^|~/g, '');
                        content += `${param.name}: ${param.value} ${param.unit}\n`;
                        content += `  计算依据: ${plainBasis}\n\n`;
                    });
                });
            }

            // 创建并下载文件
            const blob = new Blob([content], { type: format === 'csv' ? 'text/csv;charset=utf-8;' : 'text/plain;charset=utf-8;' });
            const url = URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.setAttribute('href', url);
            link.setAttribute('download', fileName);
            link.style.visibility = 'hidden';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            
            showToast(`结果已成功导出为${format.toUpperCase()}文件`);
        }

        // CSV转义处理
        function escapeCsv(value) {
            if (value === undefined || value === null) return '';
            if (typeof value !== 'string') value = String(value);
            if (value.includes(',') || value.includes('"') || value.includes('\n')) {
                return `"${value.replace(/"/g, '""')}"`;
            }
            return value;
        }

        // 获取当前日期时间字符串（用于文件名）
        function getCurrentDateTime() {
            const date = new Date();
            return date.toISOString().replace(/[:.]/g, '-').slice(0, 19);
        }

        // 显示提示消息
        function showToast(message) {
            toastMessage.textContent = message;
            toast.classList.add('show');
            
            setTimeout(() => {
                toast.classList.remove('show');
            }, 3000);
        }
    </script>
</body>
</html>
    